package secondkill.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import secondkill.Exception.GlobalException;
import secondkill.mapper.TOrderMapper;
import secondkill.pojo.TOrder;

import secondkill.pojo.TSeckillGoods;
import secondkill.pojo.TSeckillOrder;
import secondkill.pojo.TUser;
import secondkill.service.ITGoodsService;
import secondkill.service.ITOrderService;
import secondkill.service.ITSeckillGoodsService;
import secondkill.service.ITSeckillOrderService;
import secondkill.utils.MD5Util;
import secondkill.utils.UUIDUtil;
import secondkill.vo.GoodsVo;
import secondkill.vo.OrderDetailVo;
import secondkill.vo.RespBeanEnum;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 * @author Dzy
 * @since 2022-01-19
 */
@Transactional
@Service
@Slf4j
public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> implements ITOrderService {
    @Autowired
    private ITSeckillOrderService seckillOrderService;

    @Autowired
    private TOrderMapper orderMapper;

    @Autowired
    private ITSeckillGoodsService seckillGoodsService;

    @Autowired
    private ITGoodsService goodsService;

    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 秒杀订单
     * @param user 
     * @param goods
     * @return secondkill.pojo.TOrder 
     * @create 2022/1/20 21:57
     */
    @Transactional
    @Override
    public TOrder secKill(TUser user, GoodsVo goods) {
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //秒杀商品表库存减一
        TSeckillGoods secKillGoods = seckillGoodsService.getOne(new QueryWrapper<TSeckillGoods>().eq("goods_id", goods.getId()));
        secKillGoods.setStockCount(secKillGoods.getStockCount() - 1);
        //当库存大于0，id等于商品id的时候，将当前库存数量存入数据库
        seckillGoodsService.update(new UpdateWrapper<TSeckillGoods>()
                .setSql("stock_count = stock_count-1").eq("goods_id", goods.getId()).gt("stock_count", 0));

        if (secKillGoods.getStockCount() < 1) {
            //判断是否还有库存
            valueOperations.set("isStockEmpty:" + goods.getId(), "0");
            return null;
        }
        //生成订单
        TOrder order = new TOrder();
        order.setUserId(user.getId());
        order.setGoodsId(goods.getId());
        order.setDeliveryAddrId(0L);
        order.setGoodsName(goods.getGoodsName());
        order.setGoodsCount(1);
        order.setGoodsPrice(secKillGoods.getSeckillPrice());
        order.setOrderChannel(1);
        order.setStatus(0);
        order.setCreateDate(new Date());
        orderMapper.insert(order);

        //生成秒杀订单
        TSeckillOrder seckillOrder = new TSeckillOrder();
        seckillOrder.setUserId(user.getId());
        seckillOrder.setOrderId(order.getId());
        seckillOrder.setGoodsId(goods.getId());
        seckillOrderService.save(seckillOrder);

        valueOperations.set("order:" + user.getId() + ":" + goods.getId(), seckillOrder);
        return order;
    }

    /**
     * 功能描述：订单详情
     * @param orderId
     * @return secondkill.vo.OrderDetailVo
     * @create 2022/1/24 0:26
     */
    @Override
    public OrderDetailVo detail(Long orderId) {

        if (ObjectUtil.isEmpty(orderId)) {
            throw new GlobalException(RespBeanEnum.ORDER_NOT_EXIST);
        }

        TOrder order = orderMapper.selectById(orderId);
        log.info(orderId.toString());
        GoodsVo goodsVo = goodsService.findGoodsVoByGoodId(order.getGoodsId());

        OrderDetailVo detailVo = new OrderDetailVo();
        detailVo.setOrder(order);
        detailVo.setGoodsVo(goodsVo);

        return detailVo;
    }

    /**
     * 验证码校验
     * @param user
     * @param goodId
     * @param captcha
     * @return
     */
    @Override
    public boolean checkCaptcha(TUser user, Long goodId, String captcha) {
        if (ObjectUtil.isEmpty(user) || goodId < 0 || StrUtil.isEmpty(captcha)) {
            return false;
        }

        String redisCaptcha = (String) redisTemplate.opsForValue().get("captcha:" + user.getId() + ":" + goodId);

        return captcha.equals(redisCaptcha);
    }

    /**
     * 创建path
     * @param user
     * @param goodsId
     * @return
     */
    @Override
    public String createPath(TUser user, Long goodsId) {
        String str = MD5Util.MD5(UUIDUtil.uuid() + "123456");
        redisTemplate.opsForValue().set("secKillPath:" + user.getId() + ":" + goodsId, str, 60, TimeUnit.
                SECONDS);
        return str;
    }


    /**
     * 校验path的合法性
     * @param user
     * @param goodsId
     * @return
     */
    @Override
    public boolean checkPath(TUser user, Long goodsId, String path) {
        log.info("++++++++++++goodId:{}",goodsId);
        log.info("++++++++++++path:{}",path);
        if (ObjectUtil.isEmpty(user) || null == goodsId || ObjectUtil.isEmpty(path)) {
            return false;
        }
        String redisPath = (String) redisTemplate.opsForValue().get("secKillPath:" + user.getId() + ":" + goodsId);
        log.info("++++++++++++boolean:{}",path.equals(redisPath));
        return path.equals(redisPath);
    }
}
